#include "OpenGLCommon.h"

#include "TextureLoader.h"

#ifndef _OPENGL_OPENGL_DEVICE_H_
#define _OPENGL_OPENGL_DEVICE_H_

namespace Hiranipra {
	namespace Platform {
		namespace Graphics {

			class OpenGLDevice : implements IGraphicsDevice, HANDLES( WindowEvent )
			{
			public:
				OpenGLDevice( const Adapter& adapter, const Resolution& resolution, const DeviceParameters& parameters );
				virtual ~OpenGLDevice();

				virtual ITextureLoader* GetTextureLoader() const { return _textureLoader; }
				virtual IProgramLoader* GetProgramLoader() const { return _programLoader; }
				virtual IMeshLoader* GetMeshLoader() const { return _meshLoader; }

				virtual ITexture* CreateTexture( const BufferFlags flags, const uint32 width, const uint32 height, const PixelFormat format, const void* buffer ) const;
				virtual IVertexBuffer* CreateVertexBuffer( const BufferFlags flags, VertexDeclaration* vertexDecl, const uint32 elementCount, const void* buffer ) const;
				virtual IIndexBuffer* CreateIndexBuffer( const BufferFlags flags, const uint32 elementCount, const uint32 elementSize, const void* buffer ) const;

				virtual int64 GetFrameCount() const { return _frameCount; }
				virtual void BeginFrame( int clearFlags );
				virtual void EndFrame();

				virtual void SetTexture( uint32 stage, ITexture* texture );
				virtual void RenderBuffer( const PrimitiveType primitiveType, IVertexBuffer* vertexBuffer );
				virtual void RenderIndexedBuffer( const PrimitiveType primitiveType, IVertexBuffer* vertexBuffer, IIndexBuffer* indexBuffer );

				virtual void DrawDummy( float angle );

			private:
				DECLARE_HANDLER( WindowEvent );

				void OnResize();
				void RenderCorePre( IVertexBuffer* vertexBuffer );
				
			private:
				Adapter				_adapter;
				Resolution			_resolution;
				DeviceParameters	_parameters;
				IWindow*			_window;
#if WIN32
				HWND				_hWnd;
				HDC					_hDC;
				HGLRC				_hRC;
#elif defined( MACOSX )
				NSOpenGLContext		_glContext;
#endif

				TextureLoader*		_textureLoader;
				IProgramLoader*		_programLoader;
				IMeshLoader*		_meshLoader;

				int64				_frameCount;
				bool				_inFrame;

				uint32				_arrayState;
			};

		}
	}
}

#endif // _OPENGL_OPENGL_DEVICE_H_
